﻿#include "myplotframe.h"
#include "ui_myplotframe.h"

MyPlotFrame::MyPlotFrame(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyPlotFrame)
{
    ui->setupUi(this);
    Init();
}

MyPlotFrame::~MyPlotFrame()
{
    delete ui;
}

void MyPlotFrame::Init()
{
    legendMap.clear();
    legendMap["速 度(km/h)"] = SpeedC;
    legendMap[QString("当前扭力×%1(N)").arg(ratio)] = ForceSumC;
    legendMap[QString("左前扭力×%1(N)").arg(ratio)] = ForceL0C;
    legendMap[QString("右前扭力×%1(N)").arg(ratio)] = ForceR0C;
    legendMap[QString("左后扭力×%1(N)").arg(ratio)] = ForceL1C;
    legendMap[QString("右后扭力×%1(N)").arg(ratio)] = ForceR1C;
    legendMap["功 率(kW)"] = PowerC;
    legendMap["输出电压(V)"] = OutVC;
    legendMap["目标扭力(N)"] = DesForceC;
    legendMap["控制断点"] = BkPointC;
    legendMap["加 速 度"] = JSDC;

    //图例是否显示
    ui->customPlot->legend->setVisible(true);
    //图例背景色
    ui->customPlot->legend->setBrush(QBrush(QColor(255,255,255,150)));
    //设置字体
    ui->customPlot->legend->setFont(QFont("Helvetica", 9));
    //设置图例行间隔
    ui->customPlot->legend->setRowSpacing(-3);
    //在图例中添加线,四边安装轴并显示
    ui->customPlot->axisRect()->setupFullAxesBox(false);
    //将图例矩形域放到位置 顶部居中
    ui->customPlot->axisRect()->insetLayout()->setInsetAlignment(0,Qt::AlignTop|Qt::AlignVCenter);
    //设置图例文字颜色
    ui->customPlot->legend->setTextColor(QColor(50,100,100,150));
    //设置图例中图形与文字距离图例边框的距离
    ui->customPlot->legend->setMargins(QMargins(0,0,0,0));
    //设置边框隐藏
    ui->customPlot->legend->setBorderPen(Qt::NoPen);
    //设置图例行优先排列 首先填充列
    ui->customPlot->legend->setFillOrder(QCPLayoutGrid::foColumnsFirst);
    //设置五个图例自动换行
    ui->customPlot->legend->setWrap(5);
    //显示选择图例的曲线
    connect(ui->customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(SelectionChanged()));
    //设置图例位置，这里选择显示在QCPAxisRect下方，同理可设置显示在QCustomPlot中任意位置
    ui->customPlot->plotLayout()->addElement(0 , 0, ui->customPlot->legend);
    //设置显示比例
    ui->customPlot->plotLayout()->setRowStretchFactor(1, 0.001);
    //设置legend只能选择图例
    ui->customPlot->legend->setSelectableParts(QCPLegend::spItems);

    /*
    //设置基本坐标轴（左侧Y轴和下方X轴）可拖动、可缩放、曲线可选、legend可选、设置伸缩比例，使所有图例可见
    ui->customPlot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom| QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);
    //模式：框选放大
    ui->customPlot->setSelectionRectMode(QCP::SelectionRectMode::srmZoom);
    //虚线
    ui->customPlot->selectionRect()->setPen(QPen(Qt::black,1,Qt::DashLine));
    //半透明浅蓝
    ui->customPlot->selectionRect()->setBrush(QBrush(QColor(0,0,100,50)));
    */

    //是否显示网格
    ui->customPlot->xAxis->grid()->setVisible(false);
    ui->customPlot->yAxis->grid()->setVisible(false);
    // 显示x，y坐标子网格线
//    ui->customPlot->xAxis->grid()->setSubGridVisible(true);
//    ui->customPlot->yAxis->grid()->setSubGridVisible(true);

    //设置网格颜色，子网格颜色，0线颜色
    //ui->customPlot->axisRect()->setBackground(QBrush(Qt::black));//背景黑色
    ui->customPlot->xAxis->grid()->setPen(QPen(QColor(180, 180, 180), 1, Qt::PenStyle::DashLine));//网格白色虚线
    ui->customPlot->yAxis->grid()->setPen(QPen(QColor(180, 180, 180), 1, Qt::PenStyle::DashLine));//网格白色虚线
    ui->customPlot->xAxis->grid()->setSubGridPen(QPen(QColor(50, 50, 50), 1, Qt::DotLine));//网格浅色点线
    ui->customPlot->yAxis->grid()->setSubGridPen(QPen(QColor(50, 50, 50), 1, Qt::DotLine));//网格浅色点线
    ui->customPlot->xAxis->grid()->setSubGridVisible(true);//显示x轴子网格线
    ui->customPlot->yAxis->grid()->setSubGridVisible(true);//显示要轴子网格线
    ui->customPlot->xAxis->grid()->setZeroLinePen(QPen(Qt::white));//x轴0线颜色白色
    ui->customPlot->yAxis->grid()->setZeroLinePen(QPen(Qt::white));//y轴0线颜色白色

    //设置坐标轴范围，以便我们可以看到全部数据 设置X轴和Y轴的取值范围
//    ui->customPlot->xAxis->setRange(0, xAxisLen);
//    ui->customPlot->yAxis->setRange(-10, yAxisLen-10);

    //这个是坐标轴的固有属性的一个策略类，利用该策略，可以实现指定坐标轴的一些属性，比如刻度步长，刻度数目等等。
    QSharedPointer<QCPAxisTickerFixed> ticker(new QCPAxisTickerFixed);
    //设置刻度步长为1
    ticker.data()->setTickStep(5);
    //设置坐标轴有14个刻度值
    ticker.data()->setTickCount(13);

    //将刚生成的坐标轴的策略，设置到Y轴上
    ui->customPlot->yAxis->setTicker(ticker);
    //设置横坐标
    ui->customPlot->xAxis->setLabel("时间(10ms)");
    ui->customPlot->yAxis->setLabel("");
    //ui->customPlot->yAxis->setVisible(false);

    ui->customPlot->addGraph(); // red line
    ui->customPlot->graph(0)->setPen(QPen(Qt::red));
    ui->customPlot->graph(0)->setAntialiasedFill(true);
    ui->customPlot->graph(0)->setName(legendMap.key(SpeedC));


    ui->customPlot->addGraph(); // darkYellow line
    ui->customPlot->graph(1)->setPen(QPen(Qt::darkYellow));
    ui->customPlot->graph(1)->setAntialiasedFill(true);
    ui->customPlot->graph(1)->setName(legendMap.key(ForceSumC));

    ui->customPlot->addGraph(); // black line
    ui->customPlot->graph(2)->setPen(QPen(Qt::black));
    ui->customPlot->graph(2)->setAntialiasedFill(true);
    ui->customPlot->graph(2)->setName(legendMap.key(ForceL0C));

    ui->customPlot->addGraph(); // green line
    ui->customPlot->graph(3)->setPen(QPen(Qt::green));
    ui->customPlot->graph(3)->setAntialiasedFill(true);
    ui->customPlot->graph(3)->setName(legendMap.key(ForceR0C));

    ui->customPlot->addGraph(); // blue line
    ui->customPlot->graph(4)->setPen(QPen(Qt::blue));
    ui->customPlot->graph(4)->setAntialiasedFill(true);
    ui->customPlot->graph(4)->setName(legendMap.key(ForceL1C));

    ui->customPlot->addGraph(); // magenta line
    ui->customPlot->graph(5)->setPen(QPen(Qt::magenta));
    ui->customPlot->graph(5)->setAntialiasedFill(true);
    ui->customPlot->graph(5)->setName(legendMap.key(ForceR1C));

    ui->customPlot->addGraph(); // darkCyan line
    ui->customPlot->graph(6)->setPen(QPen(Qt::darkCyan));
    ui->customPlot->graph(6)->setAntialiasedFill(true);
    ui->customPlot->graph(6)->setName(legendMap.key(PowerC));

    ui->customPlot->addGraph(); // darkBlue line
    ui->customPlot->graph(7)->setPen(QPen(Qt::darkBlue));
    ui->customPlot->graph(7)->setAntialiasedFill(true);
    ui->customPlot->graph(7)->setName(legendMap.key(OutVC));

    ui->customPlot->addGraph(); // darkMagenta line
    ui->customPlot->graph(8)->setPen(QPen(Qt::darkMagenta));
    ui->customPlot->graph(8)->setAntialiasedFill(true);
    ui->customPlot->graph(8)->setName(legendMap.key(DesForceC));

    ui->customPlot->addGraph(); // darkYellow line
    ui->customPlot->graph(9)->setPen(QPen(Qt::darkYellow));
    ui->customPlot->graph(9)->setAntialiasedFill(true);
    ui->customPlot->graph(9)->setName(legendMap.key(BkPointC));

    ui->customPlot->addGraph(); // darkCyan line
    ui->customPlot->graph(10)->setPen(QPen(Qt::darkCyan));
    ui->customPlot->graph(10)->setAntialiasedFill(true);
    ui->customPlot->graph(10)->setName(legendMap.key(JSDC));

    curveGraphs[SpeedC]=ui->customPlot->graph(0);
    curveGraphs[ForceSumC]=ui->customPlot->graph(1);
    curveGraphs[ForceL0C]=ui->customPlot->graph(2);
    curveGraphs[ForceR0C]=ui->customPlot->graph(3);
    curveGraphs[ForceL1C]=ui->customPlot->graph(4);
    curveGraphs[ForceR1C]=ui->customPlot->graph(5);
    curveGraphs[PowerC]=ui->customPlot->graph(6);
    curveGraphs[OutVC]=ui->customPlot->graph(7);
    curveGraphs[DesForceC]=ui->customPlot->graph(8);
    curveGraphs[BkPointC]=ui->customPlot->graph(9);
    curveGraphs[JSDC]=ui->customPlot->graph(10);

    // make left and bottom axes transfer their ranges to right and top axes: 使左轴和下轴将其范围转移到右轴和上轴：
    //connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange)));
    //connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange)));
    int graphCount = ui->customPlot->graphCount();
    legendElementMap.clear();
    for (int i = 0; i < graphCount; ++i)
    {
        legendElementMap.insert(i,ui->customPlot->legend->takeAt(i));
    }


    menuMap.clear();
    menuMap["速度曲线"] = SpeedC;
    menuMap["涡流扭力和曲线"] =  ForceSumC;
    menuMap["左前涡流扭力曲线"] = ForceL0C;
    menuMap["右前涡流扭力曲线"] = ForceR0C;
    menuMap["左后涡流扭力曲线"] = ForceL1C;
    menuMap["右后涡流扭力曲线"] = ForceR1C;
    menuMap["功率曲线"] = PowerC;
    menuMap["输出电压曲线"] = OutVC;
    menuMap["目标扭力曲线"] = DesForceC;
    menuMap["控制断点曲线"] = BkPointC;
    menuMap["加速度曲线"] = JSDC;

    ui->btnSelectCurve->setPopupMode(QToolButton::MenuButtonPopup);
    menu=new QMenu(ui->btnSelectCurve);
    //
    actionSpeedC= new QAction(menuMap.key(SpeedC), menu);
    actionForceSumC= new QAction(menuMap.key(ForceSumC), menu);
    actionForceL0C= new QAction(menuMap.key(ForceL0C), menu);
    actionForceR0C= new QAction(menuMap.key(ForceR0C), menu);
    actionForceL1C= new QAction(menuMap.key(ForceL1C), menu);
    actionForceR1C= new QAction(menuMap.key(ForceR1C), menu);
    actionPowerC= new QAction(menuMap.key(PowerC), menu);
    actionOutVC= new QAction(menuMap.key(OutVC), menu);
    actionDesForceC= new QAction(menuMap.key(DesForceC), menu);
    actionPIDBkPointC= new QAction(menuMap.key(BkPointC), menu);
    actionJSDC= new QAction(menuMap.key(JSDC), menu);
    //
    menuActions[SpeedC]=actionSpeedC;
    menuActions[ForceSumC]=actionForceSumC;
    menuActions[ForceL0C]=actionForceL0C;
    menuActions[ForceR0C]=actionForceR0C;
    menuActions[ForceL1C]=actionForceL1C;
    menuActions[ForceR1C]=actionForceR1C;
    menuActions[PowerC]=actionPowerC;
    menuActions[OutVC]=actionOutVC;
    menuActions[DesForceC]=actionDesForceC;
    menuActions[BkPointC]=actionPIDBkPointC;
    menuActions[JSDC]=actionJSDC;
    //
    for (int i = 0; i < EndC; i++)
    {
        menuActions[i]->setCheckable(true);
        menuActions[i]->setChecked(false);
        menu->addAction(menuActions[i]);
        connect(menuActions[i], SIGNAL(triggered()), this, SLOT(CheckedAction()));
    }
    //全选
    menu->addSeparator();   //添加分割线
    actionAllMenu= new QAction("全选", menu);
    actionAllMenu->setCheckable(true);
    actionAllMenu->setChecked(false);
    menu->addAction(actionAllMenu);
    connect(actionAllMenu, SIGNAL(triggered()), this, SLOT(CheckedAction()));

    ui->btnSelectCurve->setMenu(menu);


    X = 0;
    zoomNum = 10;
    ui->btnUnZoom->setEnabled(false);
    ui->btnZoomIn->setEnabled(true) ;
    ui->btnZoomOut->setEnabled(true);

    crossHairColor = QColor(110,120,130,140);

    ui->btnCross->setEnabled(false);
    ui->btnCalc->setEnabled(false);

    menuActions[SpeedC]->setChecked(true);
    menuActions[ForceSumC]->setChecked(true);
    menuActions[PowerC]->setChecked(true);
    ui->customPlot->graph(SpeedC)->setVisible(true);
    ui->customPlot->graph(ForceSumC)->setVisible(true);
    ui->customPlot->graph(PowerC)->setVisible(true);
    ui->customPlot->legend->addElement(legendElementMap.value(SpeedC));
    ui->customPlot->legend->addElement(legendElementMap.value(ForceSumC));
    ui->customPlot->legend->addElement(legendElementMap.value(PowerC));
    //
    ui->customPlot->legend->simplify();
    ui->customPlot->replot();

//    menuActions[ForceL0C]->setChecked(true);
//    ui->customPlot->graph(ForceL0C)->setVisible(true);
//    ui->customPlot->legend->addElement(legendElementMap.value(ForceL0C));
//    menuActions[ForceL0C]->setChecked(false);
//    ui->customPlot->graph(ForceL0C)->setVisible(false);
//    ui->customPlot->legend->take(legendElementMap.value(ForceL0C));

//    menuActions[ForceR0C]->setChecked(true);
//    ui->customPlot->graph(ForceR0C)->setVisible(true);
//    ui->customPlot->legend->addElement(legendElementMap.value(ForceR0C));

    qDebug() << QString("ui->customPlot->legend->itemCount():%1").arg(ui->customPlot->legend->itemCount());

    //ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
    ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
}

void MyPlotFrame::SelectionChanged()
{
    for (int i=0; i< ui->customPlot->graphCount(); ++i)
    {
        QCPGraph *graph = ui->customPlot->graph(i);
        QCPPlottableLegendItem *item = ui->customPlot->legend->itemWithPlottable(graph);
        if (item->selected())
        {
            item->setSelected(true);
            graph->setSelection(QCPDataSelection(graph->data()->dataRange()));
        }
        ui->customPlot->update();
    }
}

void MyPlotFrame::CheckedAction()
{
    QAction *pEven = qobject_cast<QAction *>(this->sender());
    QString checkName=pEven->text();
    //qDebug()<<"the action slot is here!"+checkName;
    if("全选"==checkName)
    {
        for (int i=0;i<EndC;i++)
        {
            menuActions[i]->setChecked(pEven->isChecked());
            if(pEven->isChecked())
            {
                ui->customPlot->legend->addElement(legendElementMap.value(i));
                legendElementMap.value(i)->setVisible(true);
            }
            else
            {
                ui->customPlot->legend->take(legendElementMap.value(i));
                legendElementMap.value(i)->setVisible(false);
            }
            ui->customPlot->graph(i)->setVisible(pEven->isChecked());
        }
//        //上面的take函数拿掉了某个图例，一定需要最后调用一下这个函数，使得无效图例不占用空间，仅仅包裹
        //ui->customPlot->legend->simplify();
        ui->customPlot->replot();
    }
    else
    {
        int _Index=menuMap.value(checkName);
        bool isChecked = pEven->isChecked();
        qDebug() << QString("isChecked:%1").arg(isChecked);
        menuActions[_Index]->setChecked(isChecked);
        ui->customPlot->graph(_Index)->setVisible(isChecked);
        if(isChecked)
        {
            bool ret = ui->customPlot->legend->addElement(legendElementMap.value(_Index));
            legendElementMap.value(_Index)->setVisible(true);
            qDebug() << QString("增加图例：%1").arg(ret);
        }
        else
        {
            bool ret = ui->customPlot->legend->take(legendElementMap.value(_Index));
            legendElementMap.value(_Index)->setVisible(false);
            qDebug() << QString("删除图例：%1").arg(ret);
        }
        //ui->customPlot->legend->simplify();
        ui->customPlot->replot();
    }
}

void MyPlotFrame::InitCurve()
{

}

void MyPlotFrame::HideAllCurve()
{
    // 被选中的曲线显示
    for (int i=1;i<EndC;i++)
    {
        QCPGraph *graphItem = ui->customPlot->graph(i);
        graphItem->setVisible(false);
    }
    ui->customPlot->replot();
}

void MyPlotFrame::SetVisible(CurveTypeEnum curveTypeIndex)
{
    QCPGraph *graphItem = ui->customPlot->graph(curveTypeIndex);
    if (graphItem->selected())
        graphItem->setVisible(true);
    else
        graphItem->setVisible(false);
    ui->customPlot->replot();
}

void MyPlotFrame::DrawLine(QList<SamplingDataItem> &curveData)
{
    lineCurve->clear();
    for (int i=0;i< curveData.size()  ;i++)
    {
        X++;
        ui->customPlot->graph(SpeedC)->addData(X, curveData[i].Speed);
        ui->customPlot->graph(ForceSumC)->addData(X, curveData[i].ForceSum);
        ui->customPlot->graph(ForceL0C)->addData(X, curveData[i].BeforeForceL);
        ui->customPlot->graph(ForceR0C)->addData(X, curveData[i].BeforeForceR);
        ui->customPlot->graph(ForceL1C)->addData(X, curveData[i].AfterForceL);
        ui->customPlot->graph(ForceR1C)->addData(X, curveData[i].AfterForceR);
        ui->customPlot->graph(PowerC)->addData(X, curveData[i].Power);
        ui->customPlot->graph(OutVC)->addData(X, curveData[i].OutDesV);
        ui->customPlot->graph(DesForceC)->addData(X, curveData[i].CtrlDes);
        ui->customPlot->graph(BkPointC)->addData(X, curveData[i].SampPointNo);
        ui->customPlot->graph(JSDC)->addData(X, curveData[i].AddSpeed);
        // 使坐标范围随数据滚动
        ui->customPlot->xAxis->rescale();
        ui->customPlot->yAxis->rescale();
        ui->customPlot->replot();
    }
}

